Imports System
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Text
Imports System.Web
Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports Microsoft.SharePoint.WebPartPages
Imports Microsoft.SharePoint
Imports Microsoft.Office.Server
Imports Microsoft.Office.Server.Search.Query
Imports System.Xml.Serialization
Imports ASPNET_WebPart = System.Web.UI.WebControls.WebParts
Imports Microsoft.SharePoint.Utilities


Namespace Microsoft.SharePoint.Search.Custom


    ''' <summary>
    ''' Class for the custom XML Viewer control. The default control
    ''' does not accept connections from other controls to display data.
    ''' This control allows for a custom XSLT and XML from a 
    ''' connected webpart.
    ''' <para>
    ''' <list type="bullet">
    ''' <item>http://msdn2.microsoft.com/en-us/library/ms469765.aspx</item>
    ''' <item>http://msdn2.microsoft.com/en-us/library/ms551453.aspx</item>
    ''' <item>http://msdn.microsoft.com/msdnmag/issues/06/02/BasicInstincts/</item>
    ''' <item>http://msdn2.microsoft.com/en-us/library/ms499375.aspx</item>
    ''' <item>http://msdn2.microsoft.com/en-us/library/ms546216.aspx</item>
    ''' <item>http://msdn2.microsoft.com/en-us/library/bb219479.aspx</item>
    ''' <item>http://msdn2.microsoft.com/en-us/library/ms519321.aspx</item>
    ''' </list>
    ''' </para>
    ''' </summary>
    <XmlRoot(Namespace:="MicrosoftCustomSearch")> _
       <DefaultProperty("XSLT"), ToolboxData("<{0}:MicrosoftCustomSearch runat=server></{0}:MicrosoftCustomSearch>")> _
   Public Class CustomXMLView
        Inherits WebPart

        ''' <summary>
        ''' XML data provider connected
        ''' </summary>
        Private provider As IXMLData

        ''' <summary>
        ''' XML Document from provider
        ''' </summary>
        Private xmlData As System.Xml.XmlDocument = New System.Xml.XmlDocument()

        ''' <summary>
        ''' XSL Transform Document
        ''' </summary>
        Private xslData As System.Xml.XmlDocument = New System.Xml.XmlDocument()

        ''' <summary>
        ''' XSLT Transform object
        ''' </summary>
        Private xslTransform As System.Xml.Xsl.XslCompiledTransform = New System.Xml.Xsl.XslCompiledTransform()

        ''' <summary>
        ''' Default Transform 
        ''' Document. Provides a listing of 
        ''' all XML fields from the provider.
        ''' </summary>
        Const defaultXSLT As String = "<?xml version=""1.0"" encoding=""UTF-8""?>" + vbNewLine + "<xsl:stylesheet version=""1.0"" xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"">" + vbNewLine + "<xsl:output method=""xml"" version=""1.0"" encoding=""UTF-8"" indent=""yes""/>" + vbNewLine + "<xsl:template match=""/"">" + vbNewLine + "<xsl:copy-of select=""*""/>" + vbNewLine + "</xsl:template>" + vbNewLine + "</xsl:stylesheet>"

        ''' <summary>
        ''' XSLT Text String
        ''' </summary>
        Private _xslText As String = defaultXSLT

        '''Property to change the XSLT. The value 
        '''is only stored in the Shared Storage. 
        '''It can't be personalized.
        <Browsable(True), Category("XML Information"), DefaultValue(""), WebPartStorage(Storage.Shared), FriendlyName("XSLT"), Description("XML Transform To Apply")> _
              Public Property XSLText() As String
            Get
                Return _xslText
            End Get
            Set(ByVal value As String)
                _xslText = value
            End Set
        End Property

        ''' <summary>
        ''' Create child Controls as necessary.
        ''' </summary>
        Protected Overrides Sub CreateChildControls()

            'Create child controls when called.
            MyBase.CreateChildControls()
        End Sub

        ''' <summary>
        ''' Consume the provider data
        ''' </summary>
        ''' <param name="provider">Control that provides the data to be transformed. 
        ''' It must implement the IXMLData interface</param>
        <ASPNET_WebPart.ConnectionConsumer("XML Consumer", "IXMLData")> _
                      Public Sub SetConnectionInterface(ByVal provider As IXMLData)

            'Standard connection interface from MSDN sample.
            'Add to the collection of providers when necessary.
            Me.provider = provider

        End Sub

        ''' <summary>
        ''' Check the XML from the provider if it is set.
        ''' </summary>
        Sub checkXML()

            'Remove the existing XML data
            xmlData.RemoveAll()

            'If there is a provider set the XML data.
            If Not (Me.provider Is Nothing) Then
                xmlData = Me.provider.XMLData.Clone()
            End If

        End Sub

        ''' <summary>
        ''' Check the XSLT to verify the 
        ''' default is not needed.
        ''' </summary>
        Sub checkXSL()

            xslData.RemoveAll()
            If _xslText Is Nothing Then
                _xslText = defaultXSLT
            ElseIf _xslText = String.Empty Then
                _xslText = defaultXSLT

            End If

            xslData.LoadXml(_xslText)

        End Sub

        ''' <summary>
        ''' Render the web part.
        ''' </summary>
        ''' <param name="output">The HTML Writer to 
        ''' output the transform to</param>
        Protected Overrides Sub RenderWebPart(ByVal output As HtmlTextWriter)

            'Get the XML Data
            checkXML()

            'Get the XSLT document
            checkXSL()

            'Load the Transform
            xslTransform.Load(xslData)

            Try

                'Transform the document and send to the writer
                xslTransform.Transform(xmlData, Nothing, output)
            Catch ex As Exception
                'Write error out to trace listener
                System.Diagnostics.Trace.TraceError("Exception: " & Environment.NewLine & ex.ToString())
                output.WriteEncodedText(ex.ToString().Replace("\n", Environment.NewLine + "<br />"))
            Finally
                'Flush trace statements out to listeners
                System.Diagnostics.Trace.Flush()
            End Try
        End Sub
    End Class


End Namespace